home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / rules / prs2 / prs2locks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  15.1 KB  |  612 lines

  1. /*=======================================================================
  2.  *
  3.  * FILE:
  4.  *   prs2locks.c
  5.  *
  6.  * IDENTIFICATION:
  7.  *  $Header: /private/postgres/src/rules/prs2/RCS/prs2locks.c,v 1.18 1991/11/18 22:21:22 mer Exp $
  8.  *
  9.  * Routines to manipulate PRS2 locks...
  10.  * (there are also some useful #define's in lib/H/prs2.h
  11.  *=======================================================================
  12.  */
  13.  
  14. #include <ctype.h>
  15. #include "utils/log.h"
  16. #include "utils/palloc.h"
  17. #include "rules/prs2.h"
  18. #include "rules/rac.h"
  19.  
  20. /*-----------------------------------------------------------------------
  21.  *
  22.  * prs2FreeLocks
  23.  *
  24.  *-----------------------------------------------------------------------
  25.  */
  26. void
  27. prs2FreeLocks(lock)
  28. RuleLock lock;
  29. {
  30.     if (!RuleLockIsValid(lock))
  31.     elog(WARN,"prs2FreeLocks: Invalid rule lock");
  32.  
  33. #ifdef PRS2_DEBUG
  34.     {
  35.     /*
  36.      * yes, yes, it might help discover a couple of these
  37.      * tedious, stupid, mean, "carefull what you pfree" memory bugs...
  38.      */
  39.     long i, size;
  40.  
  41.     size = prs2LockSize(lock->numberOfLocks);
  42.     for (i=0; i<size; i++)
  43.     *( ((char *)lock) + i) = (char) 255;
  44.     }
  45. #endif PRS2_DEBUG
  46.  
  47.     pfree((Pointer)lock);
  48. }
  49.  
  50. /*-----------------------------------------------------------------------
  51.  *
  52.  * prs2MakeLocks
  53.  *
  54.  * Create an empty prs2 locks, i.e. return a pointer to a 'Prs2LocksData'
  55.  * with numberOfLocks = 0;
  56.  *-----------------------------------------------------------------------
  57.  */
  58. RuleLock
  59. prs2MakeLocks()
  60. {
  61.     RuleLock t;
  62.  
  63.     t = (RuleLock) palloc(sizeof(Prs2LocksData));
  64.  
  65.     if (t==NULL) {
  66.     elog(WARN, "prs2MakeLocks: palloc failed.");
  67.     }
  68.  
  69.     t->numberOfLocks = 0;
  70.     return(t);
  71. }
  72.  
  73.  
  74. /*-----------------------------------------------------------------------
  75.  *
  76.  * prs2AddLock
  77.  *
  78.  * Add a new lock (filled in with the given data) to a 'prs2Locks'
  79.  * Note that this frees the space occupied by 'prs2Locks' and reallocates
  80.  * some other. So this routine should be used with caution!
  81.  *-----------------------------------------------------------------------
  82.  */
  83. RuleLock
  84. prs2AddLock(oldLocks, ruleId, lockType, attributeNumber, planNumber,
  85.         partialindx, npartial)
  86. RuleLock    oldLocks;
  87. ObjectId    ruleId;
  88. Prs2LockType    lockType;
  89. AttributeNumber attributeNumber;
  90. Prs2PlanNumber    planNumber;
  91. int        partialindx;
  92. int        npartial;
  93. {
  94.     long oldSize;
  95.     long newSize;
  96.     RuleLock newLocks;
  97.     Prs2OneLock theNewLock;
  98.  
  99.     if (!RuleLockIsValid(oldLocks))
  100.     elog(WARN,"prs2AddLock: Invalid rule lock");
  101.  
  102.     /*
  103.      * allocate enough space to hold the old locks + the new one..
  104.      */
  105.     newSize = prs2LockSize(oldLocks->numberOfLocks + 1);
  106.     newLocks = (RuleLock) palloc(newSize);
  107.     if (newLocks == NULL) {
  108.     elog(WARN,"prs2AddLock: palloc failed");
  109.     }
  110.  
  111.     /*
  112.      * Now copy the old lock data to the new lock..
  113.      */
  114.     oldSize = prs2LockSize(oldLocks->numberOfLocks);
  115.     bcopy(oldLocks, newLocks, oldSize);
  116.  
  117.     /*
  118.      * update the information in newLocks..
  119.      */
  120.     newLocks->numberOfLocks = oldLocks->numberOfLocks + 1;
  121.  
  122.     theNewLock = prs2GetOneLockFromLocks(newLocks, newLocks->numberOfLocks-1);
  123.     prs2OneLockSetRuleId(theNewLock, ruleId);
  124.     prs2OneLockSetLockType(theNewLock, lockType);
  125.     prs2OneLockSetAttributeNumber(theNewLock, attributeNumber);
  126.     prs2OneLockSetPlanNumber(theNewLock, planNumber);
  127.     prs2OneLockSetPartialIndx(theNewLock, partialindx);
  128.     prs2OneLockSetNPartial(theNewLock, npartial);
  129.  
  130.     /*
  131.      * Free the space occupied by oldLocks
  132.      */
  133.     prs2FreeLocks(oldLocks);
  134.     return(newLocks);
  135. }
  136.  
  137. /*-----------------------------------------------------------------------
  138.  *
  139.  * prs2GetOneLockFromLocks
  140.  *
  141.  * Given a 'RuleLock' return a pointer to its Nth lock..
  142.  * (the first locks is lock number 0).
  143.  *-----------------------------------------------------------------------
  144.  */
  145. Prs2OneLock
  146. prs2GetOneLockFromLocks(lock, n)
  147. RuleLock lock;
  148. int n;
  149. {
  150.     Prs2OneLock t;
  151.  
  152.     if (!RuleLockIsValid(lock))
  153.     elog(WARN,"prs2GetOneLockFromLocks: Invalid rule lock");
  154.  
  155.     if (n >= lock->numberOfLocks || n<0) {
  156.     elog(WARN, "prs2GetOneLockFromLocks: lock # out of range (%d/%d)",
  157.     n, lock->numberOfLocks);
  158.     } else {
  159.     t = & ((lock->locks)[n]);
  160.     }
  161.  
  162.     return(t);
  163. }
  164.  
  165. /*------------------------------------------------------------------
  166.  * prs2OneLocksAreTheSame
  167.  *
  168.  * return true iff the given two 'Prs2OneLock' are the same...
  169.  *------------------------------------------------------------------
  170.  */
  171. bool
  172. prs2OneLocksAreTheSame(l1, l2)
  173. Prs2OneLock l1;
  174. Prs2OneLock l2;
  175. {
  176.     if (prs2OneLockGetRuleId(l1)==prs2OneLockGetRuleId(l2) &&
  177.     prs2OneLockGetLockType(l1)==prs2OneLockGetLockType(l2) &&
  178.     prs2OneLockGetAttributeNumber(l1)== prs2OneLockGetAttributeNumber(l2) &&
  179.     prs2OneLockGetPlanNumber(l1)==prs2OneLockGetPlanNumber(l2) &&
  180.     prs2OneLockGetPartialIndx(l1)==prs2OneLockGetPartialIndx(l2) &&
  181.     prs2OneLockGetNPartial(l1)==prs2OneLockGetNPartial(l2))
  182.         return(true);
  183.     else
  184.         return(false);
  185. }
  186.  
  187. /*------------------------------------------------------------------
  188.  * prs2OneLockIsMemberOfLocks
  189.  *
  190.  * return true iff the given `oneLock' is one of the locks in `locks'.
  191.  *------------------------------------------------------------------
  192.  */
  193. bool
  194. prs2OneLockIsMemberOfLocks(oneLock, locks)
  195. Prs2OneLock oneLock;
  196. RuleLock locks;
  197. {
  198.     int i, nlocks;
  199.     Prs2OneLock l;
  200.  
  201.     nlocks = prs2GetNumberOfLocks(locks);
  202.     for (i=0; i<nlocks; i++) {
  203.     l = prs2GetOneLockFromLocks(locks, i);
  204.     if (prs2OneLocksAreTheSame(oneLock, l))
  205.         return(true);
  206.     }
  207.     return(false);
  208. }
  209.  
  210. /*------------------------------------------------------------------
  211.  *
  212.  * prs2GetLocksFromTuple
  213.  *
  214.  * Extract the locks from a tuple. It returns a 'RuleLock',
  215.  *
  216.  * NOTE 1:it will never return NULL! Even if the tuple has no
  217.  * locks in it, it will return a 'RuleLock' with 'numberOfLocks'
  218.  * equal to 0.)
  219.  *
  220.  * NOTE 2: The lock returned is a COPY, so it can and must be pfreed!
  221.  * (otherwise we will have memory leaks!)
  222.  *
  223.  */
  224.  
  225. RuleLock
  226. prs2GetLocksFromTuple(tuple, buffer)
  227. HeapTuple tuple;
  228. Buffer buffer;
  229. {
  230.     return(HeapTupleGetRuleLock(tuple, buffer));
  231. }
  232.  
  233. /*------------------------------------------------------------------
  234.  *
  235.  * prs2PutLocksInTuple
  236.  *
  237.  * given a tuple, replace its current locks with the given new ones.
  238.  *
  239.  * NOTE: the old locks are pfreed!!!!!!
  240.  *
  241.  *-----------------------------------------------------------------------
  242.  */
  243.  
  244. void
  245. prs2PutLocksInTuple(tuple, buffer, relation, newLocks)
  246. HeapTuple   tuple;
  247. Buffer      buffer;
  248. Relation    relation;
  249. RuleLock   newLocks;
  250. {
  251.     HeapTupleSetRuleLock(tuple, InvalidBuffer, newLocks);
  252. }
  253.  
  254. /*------------------------------------------------------------------
  255.  *
  256.  * prs2PrintLocks
  257.  *
  258.  * print the prs2 locks in stdout. Used for debugging...
  259.  *-----------------------------------------------------------------------
  260.  */
  261.  
  262. void
  263. prs2PrintLocks(locks)
  264. RuleLock   locks;
  265. {
  266.     int i;
  267.     unsigned int type_int;
  268.     int nlocks;
  269.     Prs2OneLock oneLock;
  270.  
  271.     if (!RuleLockIsValid(locks)) {
  272.     printf("{Invalidlock}");
  273.     fflush(stdout);
  274.     return;
  275.     }
  276.  
  277.     nlocks = prs2GetNumberOfLocks(locks);
  278.     printf("{%d locks", nlocks);
  279.  
  280.     for (i=0; i<nlocks; i++) {
  281.     oneLock = prs2GetOneLockFromLocks(locks, i);
  282.     printf(" (rulid=%ld,", prs2OneLockGetRuleId(oneLock));
  283.  
  284.     /*
  285.      * print the 'type' as a char only if it is a printable
  286.      * character, otherwise print it as a hex number.
  287.      */
  288.     type_int = (unsigned int) prs2OneLockGetLockType(oneLock);
  289.     if (type_int >= 32 && type_int < 127)
  290.         printf(" type='%c'", prs2OneLockGetLockType(oneLock));
  291.     else
  292.         printf(" type=0x%x,", type_int);
  293.  
  294.     printf(" attrn=%d,", (int)prs2OneLockGetAttributeNumber(oneLock));
  295.     printf(" plano=%d,", (int)prs2OneLockGetPlanNumber(oneLock));
  296.     printf(" partial=%d/%ds)",
  297.         (int)prs2OneLockGetPartialIndx(oneLock),
  298.         (int)prs2OneLockGetNPartial(oneLock));
  299.     }
  300.  
  301.     printf(" }");
  302.     fflush(stdout);
  303. }
  304.  
  305.  
  306. /*------------------------------------------------------------------
  307.  *
  308.  * prs2CopyLocks
  309.  *
  310.  * Make a copy of a prs2 lock..
  311.  *-----------------------------------------------------------------------
  312.  */
  313. RuleLock
  314. prs2CopyLocks(locks)
  315. RuleLock locks;
  316. {
  317.     RuleLock newLocks;
  318.     int numberOfLocks;
  319.     Size size;
  320.  
  321.     if (!RuleLockIsValid(locks))
  322.     elog(WARN,"prs2CopyLocks: Invalid rule lock");
  323.  
  324.     numberOfLocks = prs2GetNumberOfLocks(locks);
  325.  
  326.     size = prs2LockSize(numberOfLocks);
  327.     newLocks = (RuleLock) palloc(size);
  328.     if (newLocks == NULL) {
  329.     elog(WARN,"prs2MakeLocks: palloc(%d) failed",size);
  330.     }
  331.     bcopy((char *)locks, (char *)newLocks, size);
  332.  
  333.     return(newLocks);
  334.  
  335. }
  336.  
  337. /*------------------------------------------------------------------
  338.  *
  339.  * prs2RemoveOneLockInPlace
  340.  *
  341.  * This is a routine that removes one lock form a 'RuleLock'.
  342.  * Note that the removal is done in place, i.e. no copy of the
  343.  * original locks is made
  344.  *-----------------------------------------------------------------------
  345.  */
  346. void
  347. prs2RemoveOneLockInPlace(locks, n)
  348. RuleLock locks;
  349. int n;
  350. {
  351.  
  352.     int i;
  353.     Prs2OneLock lock1, lock2;
  354.  
  355.     if (!RuleLockIsValid(locks)) {
  356.     elog(WARN, "prs2RemoveOneLockInPlace: called with NULL lock");
  357.     }
  358.  
  359.     if (n >= locks->numberOfLocks || n<0) {
  360.     elog(WARN, "prs2RemoveOneLockInPlace: lock # out of range (%d/%d)",
  361.     n, locks->numberOfLocks);
  362.     }
  363.  
  364.     /*
  365.      * Copy the last lock to the lock to be deleted
  366.      */
  367.     lock1 = prs2GetOneLockFromLocks(locks, n);
  368.     lock2 = prs2GetOneLockFromLocks(locks, prs2GetNumberOfLocks(locks)-1);
  369.  
  370.     prs2OneLockSetRuleId(lock1, prs2OneLockGetRuleId(lock2));
  371.     prs2OneLockSetLockType(lock1, prs2OneLockGetLockType(lock2));
  372.     prs2OneLockSetAttributeNumber(lock1,
  373.         prs2OneLockGetAttributeNumber(lock2));
  374.     prs2OneLockSetPlanNumber(lock1, prs2OneLockGetPlanNumber(lock2));
  375.     prs2OneLockSetPartialIndx(lock1, prs2OneLockGetPartialIndx(lock2));
  376.     prs2OneLockSetNPartial(lock1, prs2OneLockGetNPartial(lock2));
  377.  
  378.     /*
  379.      * decrease the number of locks
  380.      */
  381.     locks->numberOfLocks -= 1;
  382. }
  383.  
  384.  
  385. /*------------------------------------------------------------------
  386.  * prs2RemoveAllLocksOfRuleInPlace
  387.  *
  388.  * remove all the locks of the given rule, in place (i.e. no copies).
  389.  * Return true if there were locks actually removed, or false
  390.  * if no locks for this rule were found.
  391.  *-----------------------------------------------------------------------
  392.  */
  393. bool
  394. prs2RemoveAllLocksOfRuleInPlace(locks, ruleId)
  395. RuleLock locks;
  396. ObjectId ruleId;
  397. {
  398.     int i;
  399.     Prs2OneLock onelock;
  400.     bool result;
  401.  
  402.     result = false;
  403.     i = 0;
  404.     while (i<prs2GetNumberOfLocks(locks)) {
  405.     onelock = prs2GetOneLockFromLocks(locks, i);
  406.     if (prs2OneLockGetRuleId(onelock) == ruleId) {
  407.         prs2RemoveOneLockInPlace(locks, i);
  408.         result = true;
  409.     } else {
  410.         i++;
  411.     }
  412.     }
  413.  
  414.     return(result);
  415. }
  416.  
  417. /*------------------------------------------------------------------
  418.  *
  419.  * prs2RemoveAllLocksOfRule
  420.  *
  421.  * remove all the locks that have a ruleId equal to the given.
  422.  * the old `RuleLock' is destroyed and should never be
  423.  * referenced again.
  424.  * The new lock is returned.
  425.  *-----------------------------------------------------------------------
  426.  */
  427. RuleLock
  428. prs2RemoveAllLocksOfRule(oldLocks, ruleId)
  429. RuleLock oldLocks;
  430. ObjectId ruleId;
  431. {
  432.     RuleLock newLocks;
  433.     int numberOfLocks;
  434.     int i;
  435.     Prs2OneLock oneLock;
  436.  
  437.     if (!RuleLockIsValid(oldLocks)) {
  438.     elog(WARN,"prs2RemoveAllLocksOfRule: Invalid rule lock");
  439.     }
  440.  
  441.     numberOfLocks = prs2GetNumberOfLocks(oldLocks);
  442.  
  443.     /*
  444.      * create an emtpy lock
  445.      */
  446.     newLocks = prs2MakeLocks();
  447.  
  448.     /*
  449.      * copy all the locks from oldLocks to newLocks if their rule
  450.      * id is different form the given one.
  451.      */
  452.     for (i=0; i < numberOfLocks; i++) {
  453.     oneLock = prs2GetOneLockFromLocks(oldLocks, i);
  454.     if (prs2OneLockGetRuleId(oneLock) != ruleId) {
  455.         newLocks = prs2AddLock(
  456.                 newLocks,
  457.                 prs2OneLockGetRuleId(oneLock),
  458.                 prs2OneLockGetLockType(oneLock),
  459.                 prs2OneLockGetAttributeNumber(oneLock),
  460.                 prs2OneLockGetPlanNumber(oneLock),
  461.                 prs2OneLockGetPartialIndx(oneLock),
  462.                 prs2OneLockGetNPartial(oneLock));
  463.     }
  464.     }
  465.  
  466.     prs2FreeLocks(oldLocks);
  467.     return(newLocks);
  468. }
  469.  
  470. /*------------------------------------------------------------------
  471.  *
  472.  * prs2LockUnion
  473.  *
  474.  * Create the union of two locks.
  475.  * NOTE: we make COPIES of the locks. The two original locks
  476.  * are NOT modified.
  477.  *------------------------------------------------------------------
  478.  */
  479. RuleLock
  480. prs2LockUnion(lock1, lock2)
  481. RuleLock lock1;
  482. RuleLock lock2;
  483. {
  484.     RuleLock result;
  485.     Prs2OneLock oneLock;
  486.     int nlocks;
  487.     int i;
  488.  
  489.     result = prs2CopyLocks(lock1);
  490.  
  491.     nlocks = prs2GetNumberOfLocks(lock2);
  492.  
  493.     for (i=0; i<nlocks; i++) {
  494.     oneLock = prs2GetOneLockFromLocks(lock2, i);
  495.     result = prs2AddLock(result,
  496.         prs2OneLockGetRuleId(oneLock),
  497.         prs2OneLockGetLockType(oneLock),
  498.         prs2OneLockGetAttributeNumber(oneLock),
  499.         prs2OneLockGetPlanNumber(oneLock),
  500.         prs2OneLockGetPartialIndx(oneLock),
  501.         prs2OneLockGetNPartial(oneLock));
  502.     }
  503.  
  504.     return(result);
  505.  
  506. }
  507.  
  508. /*------------------------------------------------------------------
  509.  *
  510.  * prs2LockDifference
  511.  *
  512.  * Create the differenc of the two locks, i.e. all Prs2OneLocks
  513.  * that exist in `lock1' and do not exist in `lock2'.
  514.  *
  515.  * NOTE: we make COPIES of the locks. The two original locks
  516.  * are NOT modified.
  517.  *------------------------------------------------------------------
  518.  */
  519. RuleLock
  520. prs2LockDifference(lock1, lock2)
  521. RuleLock lock1;
  522. RuleLock lock2;
  523. {
  524.     RuleLock result;
  525.     Prs2OneLock oneLock;
  526.     int nlocks;
  527.     int i;
  528.  
  529.     result = prs2MakeLocks();
  530.  
  531.     nlocks = prs2GetNumberOfLocks(lock1);
  532.  
  533.     for (i=0; i<nlocks; i++) {
  534.     oneLock = prs2GetOneLockFromLocks(lock1, i);
  535.     if (!prs2OneLockIsMemberOfLocks(oneLock, lock2)) {
  536.         result = prs2AddLock(result,
  537.             prs2OneLockGetRuleId(oneLock),
  538.             prs2OneLockGetLockType(oneLock),
  539.             prs2OneLockGetAttributeNumber(oneLock),
  540.             prs2OneLockGetPlanNumber(oneLock),
  541.             prs2OneLockGetPartialIndx(oneLock),
  542.             prs2OneLockGetNPartial(oneLock));
  543.     }
  544.     }
  545.     return(result);
  546. }
  547.  
  548. /*------------------------------------------------------------------
  549.  * prs2FindLocksOfType
  550.  *
  551.  * return a copy of all the locks contained in 'locks' that
  552.  * match the given lock type.
  553.  *------------------------------------------------------------------
  554.  */
  555. RuleLock
  556. prs2FindLocksOfType(locks, lockType)
  557. RuleLock locks;
  558. Prs2LockType lockType;
  559. {
  560.     RuleLock result;
  561.     int nlocks;
  562.     Prs2OneLock oneLock;
  563.     int i;
  564.  
  565.     result = prs2MakeLocks();
  566.  
  567.     nlocks = prs2GetNumberOfLocks(locks);
  568.  
  569.     for (i=0; i<nlocks; i++) {
  570.     oneLock = prs2GetOneLockFromLocks(locks, i);
  571.     if (prs2OneLockGetLockType(oneLock) == lockType) {
  572.         result = prs2AddLock(result,
  573.                 prs2OneLockGetRuleId(oneLock),
  574.                 prs2OneLockGetLockType(oneLock),
  575.                 prs2OneLockGetAttributeNumber(oneLock),
  576.                 prs2OneLockGetPlanNumber(oneLock),
  577.                 prs2OneLockGetPartialIndx(oneLock),
  578.                 prs2OneLockGetNPartial(oneLock));
  579.     }
  580.     }
  581.  
  582.     return(result);
  583.  
  584. }
  585.  
  586. /*------------------------------------------------------------------
  587.  * prs2RemoveLocksOfTypeInPlace
  588.  *
  589.  * remove all the locks of the given type in place.
  590.  *------------------------------------------------------------------
  591.  */
  592. void
  593. prs2RemoveLocksOfTypeInPlace(locks, lockType)
  594. RuleLock locks;
  595. Prs2LockType lockType;
  596. {
  597.     int i;
  598.     Prs2OneLock onelock;
  599.  
  600.     i = 0;
  601.     while (i<prs2GetNumberOfLocks(locks)) {
  602.     onelock = prs2GetOneLockFromLocks(locks, i);
  603.     if (prs2OneLockGetLockType(onelock) == lockType) {
  604.         prs2RemoveOneLockInPlace(locks, i);
  605.     } else {
  606.         i++;
  607.     }
  608.     }
  609.  
  610. }
  611.  
  612.